{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "776935d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import required libraries for data handling, API connections, and model training\n",
    "import os\n",
    "import re\n",
    "import math\n",
    "import json\n",
    "import random\n",
    "from dotenv import load_dotenv\n",
    "from huggingface_hub import login\n",
    "import matplotlib.pyplot as plt\n",
    "from datasets import load_dataset\n",
    "import numpy as np\n",
    "import pickle\n",
    "from collections import Counter\n",
    "from openai import OpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "04ef96aa",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load API keys from .env file\n",
    "load_dotenv(override=True)\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', '####-####-####-####')\n",
    "os.environ['HF_TOKEN'] = os.getenv('HF_TOKEN', '####-####-####-####')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "8458f9e7",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Note: Environment variable`HF_TOKEN` is set and is the current active token independently from the token you've just configured.\n"
     ]
    }
   ],
   "source": [
    "# Initialize OpenAI client and login to HuggingFace\n",
    "openai = OpenAI()\n",
    "\n",
    "hf_token = os.environ['HF_TOKEN']\n",
    "login(hf_token, add_to_git_credential=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0263f64b",
   "metadata": {},
   "source": [
    "# Step 1\n",
    "\n",
    "### Prepare our data for fine-tuning in JSONL (JSON Lines) format and upload to OpenAI"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0302c73d",
   "metadata": {},
   "source": [
    "### Load and Cache Dataset\n",
    "Download banking77 dataset or load from cache (for slow internet)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "a85d7fbd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loading from cached pickle files...\n",
      "✓ Loaded 10003 train and 3080 test samples from cache\n"
     ]
    }
   ],
   "source": [
    "from data_cleaner import clean_dataset\n",
    "\n",
    "# Check if pickle files exist, otherwise download\n",
    "if os.path.exists('train.pkl') and os.path.exists('test.pkl'):\n",
    "    print(\"Loading from cached pickle files...\")\n",
    "    with open('train.pkl', 'rb') as f:\n",
    "        train = pickle.load(f)\n",
    "    with open('test.pkl', 'rb') as f:\n",
    "        test = pickle.load(f)\n",
    "    print(f\"✓ Loaded {len(train)} train and {len(test)} test samples from cache\")\n",
    "else:\n",
    "    print(\"✓ Downloading dataset from HuggingFace...\")\n",
    "    dataset = load_dataset(\"PolyAI/banking77\")\n",
    "    \n",
    "    # Clean the data\n",
    "    print(\"Cleaning dataset...\")\n",
    "    train = clean_dataset(dataset['train'], min_length=10, max_samples_per_intent=200)\n",
    "    test = clean_dataset(dataset['test'], min_length=10)\n",
    "    \n",
    "    # Save for next time\n",
    "    with open('train.pkl', 'wb') as f:\n",
    "        pickle.dump(train, f)\n",
    "    with open('test.pkl', 'wb') as f:\n",
    "        pickle.dump(test, f)\n",
    "    print(f\"✓ Cleaned and saved {len(train)} train and {len(test)} test samples\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df2d9c9d",
   "metadata": {},
   "source": [
    "# Step 2\n",
    "\n",
    "### Create fine-tuning job on OpenAI and monitor training progress"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9a608e40",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✓ Created 200 train and 50 validation examples\n"
     ]
    }
   ],
   "source": [
    "# Convert to list format for easier handling\n",
    "train_list = [{'text': train[i]['text'], 'label': train[i]['label']} for i in range(len(train))]\n",
    "\n",
    "# Create fine-tuning subsets\n",
    "fine_tune_train = train_list[:200] #800\n",
    "fine_tune_validation = train_list[200:250] #4,000\n",
    "\n",
    "print(f\"✓ Created {len(fine_tune_train)} train and {len(fine_tune_validation)} validation examples\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e878a4f0",
   "metadata": {},
   "source": [
    "### Format Messages for OpenAI\n",
    "Create training and inference message formats\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e305e49e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'role': 'system',\n",
       "  'content': 'You classify banking customer queries into intents. Reply only with the intent name, no explanation'},\n",
       " {'role': 'user', 'content': 'I am still waiting on my card?'},\n",
       " {'role': 'assistant', 'content': 'card_arrival'}]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from banking_intents import get_intent\n",
    "\n",
    "def messages_for_training(item):\n",
    "    \"\"\"Create messages for fine-tuning - includes the correct answer\"\"\"\n",
    "    system_message = \"You classify banking customer queries into intents. Reply only with the intent name, no explanation\"\n",
    "    return [\n",
    "        {\"role\": \"system\", \"content\": system_message},\n",
    "        {\"role\": \"user\", \"content\": item['text']},\n",
    "        {\"role\": \"assistant\", \"content\": get_intent(item['label'])}\n",
    "    ]\n",
    "\n",
    "def messages_for_inference(item):\n",
    "    \"\"\"Create messages for prediction - NO answer (model must predict)\"\"\"\n",
    "    system_message = \"You classify banking customer queries into intents. Reply only with the intent name, no explanation\"\n",
    "    return [\n",
    "        {\"role\": \"system\", \"content\": system_message},\n",
    "        {\"role\": \"user\", \"content\": item['text']}\n",
    "    ]\n",
    "\n",
    "# Test training format\n",
    "messages_for_training(train[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "c3a27241",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\"messages\": [{\"role\": \"system\", \"content\": \"You classify banking customer queries into intents. Reply only with the intent name, no explanation\"}, {\"role\": \"user\", \"content\": \"I am still waiting on my card?\"}, {\"role\": \"assistant\", \"content\": \"card_arrival\"}]}\n",
      "{\"messages\": [{\"role\": \"system\", \"content\": \"You classify banking customer queries into intents. Reply only with the intent name, no explanation\"}, {\"role\": \"user\", \"content\": \"What can I do if my card still hasn't arrived after 2 weeks?\"}, {\"role\": \"assistant\", \"content\": \"card_arrival\"}]}\n",
      "{\"messages\": [{\"role\": \"system\", \"content\": \"You classify banking customer queries into intents. Reply only with the intent name, no explanation\"}, {\"role\": \"user\", \"content\": \"I have been waiting over a week. Is the card still coming?\"}, {\"role\": \"assistant\", \"content\": \"card_arrival\"}]}\n"
     ]
    }
   ],
   "source": [
    "def make_jsonl(data, start=0, end=None):\n",
    "    \"\"\"Convert data to JSONL format for training\"\"\"\n",
    "    result = \"\"\n",
    "    end = end or len(data)\n",
    "    \n",
    "    for i in range(start, end):\n",
    "        item = data[i]\n",
    "        messages = messages_for_training(item)  # Use training format\n",
    "        messages_str = json.dumps(messages)\n",
    "        result += '{\"messages\": ' + messages_str +'}\\n'\n",
    "    \n",
    "    return result.strip()\n",
    "\n",
    "print(make_jsonl(train, start=0, end=3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bb0e75d6",
   "metadata": {},
   "source": [
    "### Convert to JSONL and Upload\n",
    "Prepare data in OpenAI format and upload to their servers\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "dd4affd3",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# Write JSONL string to file\n",
    "def write_jsonl(data, filename, start=0, end=None):\n",
    "    with open(filename, \"w\") as f:\n",
    "        jsonl = make_jsonl(data, start, end)\n",
    "        f.write(jsonl)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "8c5bf74c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0. I am still waiting on my card? → Intent: 11\n",
      "1. What can I do if my card still hasn't arrived after 2 weeks? → Intent: 11\n",
      "2. I have been waiting over a week. Is the card still coming? → Intent: 11\n"
     ]
    }
   ],
   "source": [
    "# Verify data loaded correctly - show first 3 examples\n",
    "for i in range(3):\n",
    "    print(f\"{i}. {train[i]['text']} → Intent: {train[i]['label']}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "8b3bc0a9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✓ Uploaded train: file-U84ceTSvNn833d6aPpWX4i\n",
      "✓ Uploaded validation: file-ARVTnFJnHn2HpE9UAr9mr5\n"
     ]
    }
   ],
   "source": [
    "def prepare_and_upload(data, filename):\n",
    "    \"\"\"Write JSONL and upload to OpenAI\"\"\"\n",
    "    write_jsonl(data, filename)\n",
    "    with open(filename, \"rb\") as f:\n",
    "        return openai.files.create(file=f, purpose=\"fine-tune\")\n",
    "\n",
    "# Use it\n",
    "train_file = prepare_and_upload(fine_tune_train, \"fine_tune_train.jsonl\")\n",
    "validation_file = prepare_and_upload(fine_tune_validation, \"fine_tune_validation.jsonl\")\n",
    "\n",
    "print(f\"✓ Uploaded train: {train_file.id}\")\n",
    "print(f\"✓ Uploaded validation: {validation_file.id}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "f6147112",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "FineTuningJob(id='ftjob-FN3B5dQQOhuk4UVOZ5X4CqBU', created_at=1761873619, error=Error(code=None, message=None, param=None), fine_tuned_model=None, finished_at=None, hyperparameters=Hyperparameters(batch_size='auto', learning_rate_multiplier='auto', n_epochs=1), model='gpt-4o-mini-2024-07-18', object='fine_tuning.job', organization_id='org-OFfqVJ5fIDV1i5BqCwT86Px6', result_files=[], seed=42, status='validating_files', trained_tokens=None, training_file='file-U84ceTSvNn833d6aPpWX4i', validation_file='file-ARVTnFJnHn2HpE9UAr9mr5', estimated_finish=None, integrations=[], metadata=None, method=Method(type='supervised', dpo=None, reinforcement=None, supervised=SupervisedMethod(hyperparameters=SupervisedHyperparameters(batch_size='auto', learning_rate_multiplier='auto', n_epochs=1))), user_provided_suffix='banking_intent', usage_metrics=None, shared_with_openai=False, eval_id=None)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Create fine-tuning job - training happens on OpenAI's servers\n",
    "openai.fine_tuning.jobs.create(\n",
    "    training_file=train_file.id,\n",
    "    validation_file=validation_file.id,\n",
    "    model=\"gpt-4o-mini-2024-07-18\",\n",
    "    seed=42,  # For reproducibility\n",
    "    hyperparameters={\"n_epochs\": 1},  # Training passes\n",
    "    suffix=\"banking_intent\"  # Custom model name\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dd2fe11f",
   "metadata": {},
   "source": [
    "### Monitor Training Progress\n",
    "Check job status and view training events\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "bb98e266",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Status: ftjob-FN3B5dQQOhuk4UVOZ5X4CqBU\n",
      "Status: succeeded\n"
     ]
    }
   ],
   "source": [
    "# List most recent fine-tuning job to check status\n",
    "job = openai.fine_tuning.jobs.list(limit=1).data[0]\n",
    "print(f\"Status: {job.id}\")\n",
    "print(f\"Status: {job.status}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "a503b4f3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "FineTuningJob(id='ftjob-FN3B5dQQOhuk4UVOZ5X4CqBU', created_at=1761873619, error=Error(code=None, message=None, param=None), fine_tuned_model='ft:gpt-4o-mini-2024-07-18:hope-ogbons:banking-intent:CWYGwKT5', finished_at=1761874273, hyperparameters=Hyperparameters(batch_size=1, learning_rate_multiplier=1.8, n_epochs=1), model='gpt-4o-mini-2024-07-18', object='fine_tuning.job', organization_id='org-OFfqVJ5fIDV1i5BqCwT86Px6', result_files=['file-N5eUNWYhwaxJt2KSYEjpBU'], seed=42, status='succeeded', trained_tokens=9105, training_file='file-U84ceTSvNn833d6aPpWX4i', validation_file='file-ARVTnFJnHn2HpE9UAr9mr5', estimated_finish=None, integrations=[], metadata=None, method=Method(type='supervised', dpo=None, reinforcement=None, supervised=SupervisedMethod(hyperparameters=SupervisedHyperparameters(batch_size=1, learning_rate_multiplier=1.8, n_epochs=1))), user_provided_suffix='banking_intent', usage_metrics=None, shared_with_openai=False, eval_id=None)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Get detailed information about the job\n",
    "openai.fine_tuning.jobs.retrieve(job.id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d7008bdd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[FineTuningJobEvent(id='ftevent-nsKcQzrX5kAlH71815ndMGr4', created_at=1761875045, level='info', message='The job has successfully completed', object='fine_tuning.job.event', data={}, type='message'),\n",
       " FineTuningJobEvent(id='ftevent-BWM8ClTEEWO3rVf1bn8WdszY', created_at=1761875039, level='info', message='Usage policy evaluations completed, model is now enabled for sampling', object='fine_tuning.job.event', data={}, type='message'),\n",
       " FineTuningJobEvent(id='ftevent-yyxA2AU1GvpP5Ii3WbxlDktc', created_at=1761875039, level='info', message='Moderation checks for snapshot ft:gpt-4o-mini-2024-07-18:hope-ogbons:banking-intent:CWYGwKT5 passed.', object='fine_tuning.job.event', data={'blocked': False, 'results': [{'flagged': False, 'category': 'harassment/threatening', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'sexual', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'sexual/minors', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'propaganda', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'hate', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'hate/threatening', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'illicit', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'violence', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'advice', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'self-harm/intent', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'self-harm/instructions', 'enforcement': 'non_blocking'}, {'flagged': False, 'category': 'sensitive', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'highly-sensitive', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'biological threats', 'enforcement': 'blocking'}, {'flagged': False, 'category': 'cyber security threats', 'enforcement': 'blocking'}], 'finetuned_model_checkpoint_id': 'ft:gpt-4o-mini-2024-07-18:hope-ogbons:banking-intent:CWYGwKT5'}, type='moderation_checks'),\n",
       " FineTuningJobEvent(id='ftevent-yojUh3akovLiyB1gX7NN4UCn', created_at=1761874276, level='info', message='Evaluating model against our usage policies', object='fine_tuning.job.event', data={}, type='message'),\n",
       " FineTuningJobEvent(id='ftevent-tGdquF1ECX2kirD3YMFZ68H2', created_at=1761874276, level='info', message='New fine-tuned model created', object='fine_tuning.job.event', data={}, type='message'),\n",
       " FineTuningJobEvent(id='ftevent-sMiUeWRPavauz8yO7SJfWA3U', created_at=1761874248, level='info', message='Step 200/200: training loss=0.00, validation loss=0.00, full validation loss=0.00', object='fine_tuning.job.event', data={'step': 200, 'train_loss': 0.00013084411330055445, 'valid_loss': 0.0001373291015625, 'total_steps': 200, 'full_valid_loss': 0.000696044921875, 'train_mean_token_accuracy': 1.0, 'valid_mean_token_accuracy': 1.0, 'full_valid_mean_token_accuracy': 1.0}, type='metrics'),\n",
       " FineTuningJobEvent(id='ftevent-C6XLihn75vu22sJBkSbBDZ6L', created_at=1761874239, level='info', message='Step 199/200: training loss=0.00', object='fine_tuning.job.event', data={'step': 199, 'train_loss': 8.850097947288305e-05, 'total_steps': 200, 'train_mean_token_accuracy': 1.0}, type='metrics'),\n",
       " FineTuningJobEvent(id='ftevent-LUGsXqTJjgAIw8fQQLjaTewj', created_at=1761874239, level='info', message='Step 198/200: training loss=0.00', object='fine_tuning.job.event', data={'step': 198, 'train_loss': 0.00010757446580100805, 'total_steps': 200, 'train_mean_token_accuracy': 1.0}, type='metrics'),\n",
       " FineTuningJobEvent(id='ftevent-4peUk2wOGyP7Pe0COgCEMtI1', created_at=1761874239, level='info', message='Step 197/200: training loss=0.00', object='fine_tuning.job.event', data={'step': 197, 'train_loss': 0.00012130737013649195, 'total_steps': 200, 'train_mean_token_accuracy': 1.0}, type='metrics'),\n",
       " FineTuningJobEvent(id='ftevent-SyIiUrcSzUzoYBZMAMfgH3zh', created_at=1761874234, level='info', message='Step 196/200: training loss=0.00', object='fine_tuning.job.event', data={'step': 196, 'train_loss': 9.689330909168348e-05, 'total_steps': 200, 'train_mean_token_accuracy': 1.0}, type='metrics')]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# View training events log (last 10 events)\n",
    "openai.fine_tuning.jobs.list_events(fine_tuning_job_id=job.id, limit=10).data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb837277",
   "metadata": {},
   "source": [
    "# Step 3\n",
    "\n",
    "### Use the fine-tuned model to classify banking queries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "d710b977",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'ft:gpt-4o-mini-2024-07-18:hope-ogbons:banking-intent:CWYGwKT5'"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Get the fine-tuned model ID (only works after training succeeds)\n",
    "fine_tuned_model_name = openai.fine_tuning.jobs.retrieve(job.id).fine_tuned_model\n",
    "fine_tuned_model_name"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9518959",
   "metadata": {},
   "source": [
    "### Use Fine-Tuned Model\n",
    "Classify banking queries with the trained model\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "5afef0bb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'card_arrival'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def gpt_fine_tuned(item):\n",
    "    \"\"\"Classify banking query using fine-tuned model\"\"\"\n",
    "    response = openai.chat.completions.create(\n",
    "        model=fine_tuned_model_name,\n",
    "        messages=messages_for_inference(item),  # Use inference format (no label)\n",
    "        seed=42,\n",
    "        max_tokens=20\n",
    "    )\n",
    "    intent = response.choices[0].message.content.strip()\n",
    "    return intent\n",
    "\n",
    "gpt_fine_tuned(train[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "5198c5c5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model name: ft:gpt-4o-mini-2024-07-18:hope-ogbons:banking-intent:CWYGwKT5\n",
      "\n",
      "Job ID: ftjob-FN3B5dQQOhuk4UVOZ5X4CqBU\n",
      "Status: succeeded\n",
      "Fine-tuned model: ft:gpt-4o-mini-2024-07-18:hope-ogbons:banking-intent:CWYGwKT5\n"
     ]
    }
   ],
   "source": [
    "# Verify training completed successfully\n",
    "print(\"Model name:\", fine_tuned_model_name)\n",
    "print()\n",
    "\n",
    "print(\"Job ID:\", job.id)\n",
    "job_status = openai.fine_tuning.jobs.retrieve(job.id)\n",
    "print(\"Status:\", job_status.status)\n",
    "print(\"Fine-tuned model:\", job_status.fine_tuned_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "33683c39",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test example: {'text': 'How do I locate my card?', 'label': 11}\n",
      "Predicted intent: card_arrival\n"
     ]
    }
   ],
   "source": [
    "# Test the fine-tuned model on a single example\n",
    "print(\"Test example:\", test[0])\n",
    "print(\"Predicted intent:\", gpt_fine_tuned(test[0]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "216f3164",
   "metadata": {},
   "source": [
    "### Evaluate Model Performance\n",
    "Test on 100 examples and calculate accuracy\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "b500717d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✓ Converted 3080 test examples to list format\n"
     ]
    }
   ],
   "source": [
    "# Convert test to list format\n",
    "test_list = [{'text': test[i]['text'], 'label': test[i]['label']} for i in range(len(test))]\n",
    "\n",
    "print(f\"✓ Converted {len(test_list)} test examples to list format\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "f0787061",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Testing Gpt Fine Tuned on 100 examples...\n",
      "\n",
      "\u001b[92m✓ 1: How do I locate my card?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 2: I still have not received my new card, I ordered over a week...\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 3: I ordered a card but it has not arrived. Help please!\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 4: Is there a way to know when my card will arrive?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 5: My card has not arrived yet.\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 6: When will I get my card?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 7: Do you know if there is a tracking number for the new card y...\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 8: i have not received my card\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 9: still waiting on that card\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 10: Is it normal to have to wait over a week for my new card?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 11: How do I track my card?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 12: How long does a card delivery take?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 13: I still don't have my card after 2 weeks.  What should I do?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 14: still waiting on my new card\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 15: I am still waiting for my card after 1 week.  Is this ok?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 16: I have been waiting longer than expected for my bank card, c...\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 17: I've been waiting longer than expected for my card.\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 18: Why hasn't my card been delivered?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 19: Where is my new card? I have been waiting a week!\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 20: My card still hasn't arrived after 2 weeks. Is it lost?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 21: I did not get my card yet, is it lost?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 22: Status of the card I ordered.\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 23: How long should my new card take to arrive?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 24: I ordered my card 2 weeks ago and it still isn't here? What ...\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 25: My card has not arrived yet, where is it?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 26: What is the tracking number for my card that was mailed?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 27: I think something went wrong with my card delivery as I have...\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 28: I'm still waiting for delivery of my new card, why is it tak...\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 29: I ordered a card a week ago, and it's still not here. What d...\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 30: i want to track the card you sent\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 31: My card hasn't arrived yet.\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 32: I was expecting my new card and am wondering why I haven't r...\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 33: How do I know when my card will arrive?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 34: I'm still waiting on my card to be delivered.\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 35: Does the card you sent have a way to track to it?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 36: I ordered a card and I still haven't received it. It's been ...\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 37: I'm starting to think my card is lost because it still hasn'...\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 38: Is there tracking info available?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 39: What is the tracking number for the card you sent?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 40: Where is the tracking number for the card you sent me?\n",
      "   Predicted: card_arrival | Actual: card_arrival\u001b[0m\n",
      "\u001b[92m✓ 41: Why won't my card show up on the app?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 42: I would like to reactivate my card.\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 43: Where do I link the new card?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 44: I have received my card, can you help me put it in the app?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 45: How do I link a card that I already have?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 46: I received my new card, but I don't see it in the app anywhe...\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 47: How do I re-add a card to the app?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 48: How do I add the card to my account?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 49: Can I put my old card back into the system? I just found it/\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 50: I have one of your cards already, how do I link it?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 51: How do I link a new card?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 52: Can I link an existing card?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 53: How do I link one your card if I have one already?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 54: How do I add a card to the app?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 55: Can I link my new card?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 56: Hello, I found the card I misplaced and I need to reactive i...\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 57: Can you tell me how to link one of your cards that I already...\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 58: How do I view the card I received in the app?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 59: Where on the website do I go to link my card?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 60: I found my card, can I add it to the app?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 61: How do I link to my credit card with you?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 62: I've received my card so now I need to know how to sync it t...\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 63: I found my card, I would like to reactivate it.\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 64: How do I link this new card?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 65: Can I reactivate my lost card that I found this morning in m...\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 66: how do I link an already existing card?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 67: The app doesn't show the card I received.\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 68: how do I link a card I already have?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 69: I would like to link my card. How do I do it?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 70: Can you please show me where I can find the location to link...\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 71: Where do I go if I want to link my new card?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 72: Is there a way to make my old card usable with the app?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 73: Can I reactivate a card I thought I lost?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 74: How do I link my card\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 75: Where do I need to go in the app to enter my card info?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 76: I have found my lost or stolen card. Is there a way I can li...\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 77: Could you help me reactivate my card? It was previously lost...\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 78: I already have one of your cards, how do I link them?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 79: How do I link my replacement card?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[92m✓ 80: Can I link another card to my account?\n",
      "   Predicted: card_linking | Actual: card_linking\u001b[0m\n",
      "\u001b[91m✗ 81: I need to know your exchange rates.\n",
      "   Predicted: exchange_rates | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 82: What exchange rates do you offer?\n",
      "   Predicted: currency_exchange | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 83: How did you come up with your exchange rates?\n",
      "   Predicted: currency_conversion | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 84: Where do you guys acquire your exchange rate?\n",
      "   Predicted: foreign_exchange_rates | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 85: How do I find the exchange rate?\n",
      "   Predicted: exchange_rate_arrival | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 86: What are your international exchange rates?\n",
      "   Predicted: currency_exchange | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 87: How often do your exchange rates change\n",
      "   Predicted: exchange_rate_change | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 88: Please advise what is the exchange rate\n",
      "   Predicted: currency_exchange | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 89: How are exchange rates calculated?\n",
      "   Predicted: currency_conversion | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 90: what are exchange rates based on\n",
      "   Predicted: currency_conversion | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 91: what are exchange rates\n",
      "   Predicted: exchange_rate_arrival | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 92: What are the most current exchange rates?\n",
      "   Predicted: exchange_rates | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 93: Can you explain your exchange rate policy to me?\n",
      "   Predicted: currency_conversion | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 94: Is it a good time to exchange?\n",
      "   Predicted: currency_exchange | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 95: What is the exchange rate like on this app?\n",
      "   Predicted: currency_conversion | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 96: Do you have a list of exchange rates?\n",
      "   Predicted: foreign_exchange_rates | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 97: Can you tell me where you get your exchange rates?\n",
      "   Predicted: exchange_rate_arrival | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 98: Will I get a curreng foreign exchange rate?\n",
      "   Predicted: currency_exchange | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 99: What currencies is an exchange rate calculated in?\n",
      "   Predicted: foreign_exchange_rates | Actual: exchange_rate\u001b[0m\n",
      "\u001b[91m✗ 100: Where do you get your exchange rates from?\n",
      "   Predicted: foreign_exchange_rates | Actual: exchange_rate\u001b[0m\n",
      "\n",
      "======================================================================\n",
      "MODEL: Gpt Fine Tuned\n",
      "TESTED: 100 examples\n",
      "CORRECT: 80 (80.0%)\n",
      "INCORRECT: 20\n",
      "======================================================================\n",
      "\n",
      "Most Common Errors:\n",
      "  exchange_rate → currency_exchange: 5 times\n",
      "  exchange_rate → currency_conversion: 5 times\n",
      "  exchange_rate → foreign_exchange_rates: 4 times\n",
      "  exchange_rate → exchange_rate_arrival: 3 times\n",
      "  exchange_rate → exchange_rates: 2 times\n"
     ]
    },
    {
     "data": {
      "image/png": "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R0ebzWazOTMzM99+UVFRZpPJZL506VKh55F3fBsbG/PJkyctlr/88stmV1dXc3Z29j1rvNP58+fNksyLFy8ucP28efPMjo6O5tTUVLPZbDafO3euwGfoqaeeMru4uFjUbzabzbm5uca/X3/9dbMk88WLFy22uXjxolmSOSYmJl/7dz8XBV27/fv3myWZ33//fWNZ3jO5c+fOAs+ruP75z3+aTSZTgbXdLa/N9957z3z16lXzd999Z46Pjzd7enqaTSaT+cCBA2az+f/ua//+/S32T05ONtva2ppnzZplsfz48ePmUqVKGctv3rxprlSpkrlZs2YW37d33nnHLMns6+trLCvo2v6We/UoasyzatUqsyTzF198kW8dANyNnlIAAOBPb/PmzbK1tVVYWJjF8rFjx8psNmvLli0Wy9u0aaOWLVsan2vWrKkePXro008/VU5OzkOp6ZdffpG9vX2+5Xnzxtw9BOxOeT0QXFxcitXW5s2b5ePjYzG0yNnZWSNGjFBycrJOnTplsf3gwYNVunRp43P79u0l6aG+eaxs2bI6efKkvvrqq2Lvs3nzZknK17tt7NixkpRvOGKjRo2M2qXbQw0bNGhQ7PP417/+pYoVK6pSpUp6/PHHlZiYqFdeeUWjR4+WJDk6OhrbZmRk6Mcff1Tbtm1lNpuVlJR0z+P7+vqqUaNGFsvKli2rjIwMi2GMxfHTTz9JksqVK1fg+pUrV6pbt27GM1OvXj21bNnSYgjf1atXtWfPHg0ZMkQ1a9a02P9BJkQvyp3X7tatW/rpp59Ut25dlS1b9r7fQClJv/76a5F/r732mkJCQjR06NB7zteWZ8iQIapYsaKqVaumbt26KSMjQ8uXL1erVq0stgsNDbX4vHbtWuXm5qpv37768ccfjb8qVaqoXr162rlzpyTp4MGDunLlikJDQy2+b4MGDZKbm1uRtf3We/Uoa8x7Bn/88cd71gEATHQOAAD+9C5duqRq1arlC3G8vb2N9Xcq6M139evXV2Zmpq5evaoqVar85pocHR0LnDfq119/NdYXxtXVVZKUlpZWrLYuXbqkxx9/PN/yO8//scceM5bf/SM370fmtWvXitVecUyfPl09evRQ/fr19dhjjykwMFDPP/+8mjRpUug+ly5dko2NTb63/VWpUkVly5bNdx/vPg/p9rkU9zx69OihUaNGyWQy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YcMC1504cUJjx47VvHnzCgwGCuPq6qpq1aopMTHR4v4nJiYW2IspT+XKlVWtWjV9/fXXGjhwYLHaatCggTZv3myxLG9+rYehuDW9/vrrOnPmjHbv3q2AgADFxMQYz27es1zQ0LHiOHTokHJzcxUdHW28lfE///nPfR3Dzc1NlStX1oEDB4xnNycnR4cPH1azZs0kFf97e78SExM1aNAg40UF6enpSk5OttimdOnSBT7Lp06dKvJZLlWqlPz9/eXv769p06apbNmy+uyzzwoMZQEAAAAAf1zFDqVcXFw0btw4jRkzRrm5uXryySd148YNJSYmytXVVSEhIYqPj9d7772n/fv3q0WLFho/frxCQkJ07NgxlStXTtOmTVOnTp1Up04d9evXT9nZ2dq8ebPCw8OLVUO9evWUkpKi1atXq3Xr1oqPj9e6dfc3vtfFxUUhISEaP3683N3dValSJU2bNs3iLXP169fXwIEDFRwcrOjoaDVv3lxXr17Vjh071KRJk0LnYSpO/XFxcWrVqpVSU1M1fvz4fD1uPD09tWPHDrVr10729vYqV66cpk6dqu7du6tmzZrq3bu3bGxsdPToUZ04cUIzZ868rxoaNmyoFStW3HN+oIKMHz9e06ZNU506ddSsWTPFxMToyJEjFkOxChIZGamwsDC5ubkpMDBQWVlZOnjwoK5du2Yx9CrPCy+8oPnz5ys8PFxDhw7VkSNHFBsbK0n5ep89qHvVlJSUpKlTp2rNmjVq166d5s+fr5dfflm+vr7y8vLSpEmT1LhxY40cOVKhoaEqXbq0du7cqT59+qhChQr3bL9u3bq6deuWFi9erKCgICUmJmrp0qX3fR7//Oc/FRUVpbp166phw4ZavHixrl27Zlyn4nxvH0S9evW0du1aBQUFyWQyacqUKfl6I3p6emrPnj3q16+f7O3tVaFCBYWHh+uJJ57QqFGjNGzYMDk5OenUqVPatm2b3nzzTW3atElff/21nnrqKZUrV06bN29Wbm6uxfBaAAAAAMCfw329fW/GjBmaMmWKoqKi5O3trcDAQMXHx6t27dq6evWqhg4dqoiICLVo0ULS7R/+lStXNiYp9/Pz04cffqiNGzeqWbNm6tixo7788stit//0009rzJgxGjVqlJo1a6Z9+/ZpypQp93MKkqT58+erTZs26t69u/z9/dWuXTt5e3tb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LXS730VPqfPnzyszM1OdO3eWs7Oz8ff+++/rwoULxnZ9+vRRr169NGfOHM2bN88IpCTpyJEjxg/ZwuT1ppFu/5CvUqWKrly5Yiz74IMP1K5dO1WpUkXOzs569dVXlZKSYnEMT09Pi94veSGEJH399de6deuWRQ8tNzc3NWjQwPh8/Phx5eTkqH79+hbnunv3botzLUrp0qUtzkWSfvjhBw0fPlz16tWTm5ubXF1dlZ6enq/+ux09elTTp0+3qGX48OG6fPmyMjMz822fN7yusL/g4GD9+uuvevbZZy2GPua5cuWKvvvuu3veq+Jo1apVvmUtW7bMd347d+60OL+GDRtKksX1vvt63nlfjxw5ourVqxcYSEm3A6y//e1vWr58uaTboV6tWrX01FNP3fMcjhw5oubNmxcYSEnS6dOn1a5dO4tl7dq10+nTpy2W3Vm/k5OTXF1djfqbNWsmb29vI9zdvXu3rly5oj59+ki6fY3S09NVvnx5i+t08eJFi2tUq1YtI5CSpKZNm6pTp05q3Lix+vTpo3fffVfXrl0r8DwuXLigW7duWZyLnZ2dfHx8ijyXqlWrSpLF9/ROkyZN0o0bN4y/b775psDtAAAAAAC/P7+Lt++lp6dLuj0Ez8PDw2LdnT03MjMzdejQIdna2uYb6ubo6HjPduzsLHtOmEwmY5jU/v37NXDgQEVGRiogIEBubm5avXq1oqOji32M4khPT5etra1xHndydnYu1jEcHR1lMpksloWEhOinn37SwoULVatWLdnb26tNmzb3nJA6PT1dkZGReuaZZ/KtK6hnioeHR74Q4U579uzRyJEj9dprr+W7Vnm1F8XG5nZOemcHvoLCLel2+HKvZenp6QoKCtLcuXPzbZsXeEhF39fiPFvDhg3T//7v/2rixImKiYnR4MGD892jghTn2MVxr+dy4MCBWrVqlSZOnKhVq1YpMDBQ5cuXl3T7GlWtWrXAec3unKj87mtra2urbdu2ad++fdq6dasWL16syZMn64svvlDt2rUfyrnkXcPCvmP29vYW/40AAAAAAPxx/C56St05YXfdunUt/mrUqGFsN3bsWNnY2GjLli1atGiRPvvsM2NdkyZNtGPHjgeuYd++fapVq5YmT56sVq1aqV69esYk0MXl5eUlOzs7i8mbb9y4oXPnzhmfmzdvrpycHF25ciXfuVap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G31/Lly4oJ49e6pFixbauXOn3nzzTY0ePdri/SW9Fte6dOmSLly4YPEDAAAAACgbTPmFrUWl2KVLl+Tq6qr169crICDAvPy5555TTk6OuUvkyy+/VFhYmCIjI/Xee+9p165datiwoSSpXbt28vLy0qJFi4o9hqenpx5++GEtXLhQUkH3Va1atRQdHa1BgwYV+55p06ZpyZIl2r59u6SCTqm3335bp06dMocNo0aN0qZNm/TTTz8pMzNT9913nxYvXqy+fftKks6fP686dero+eef14wZM5SWliYvLy+lpaWpTp065mMFBQWpbdu2mjx58g0/q3nz5mngwIFKSUlRy5Ytr7tdXl6eXFxctHjxYvXo0UNSwZxSy5cvV+/evS2O+8gjj2js2LHmZYsWLdKoUaN08uTJG9ZSnIULF+qFF17QV199pe7duxe7jbu7uwYOHKhJkyYVWXfs2DE1aNBAu3btkq+vr6SCMKNatWr6/vvvFRgYqA0bNqhjx46Kj49Xr169zO8NDAzUhQsXLELASZMmafPmzVq7dq152YkTJ+Th4aGDBw/K29tbgYGBys3N1ebNm83btG3bVp06dVJMTIzWrVunkJAQpaamytvbu0jN27ZtU7t27XT8+HHVrl1bGRkZcnd31/r169WhQ4cbfl6LFi3SpEmTlJqaKpPJJKlg2KGLi4vi4+PVpUsXSVKPHj104cIF2draqkKFClqzZo1MJpN++eUXNWrUSAkJCQoKCiqy/8LPav369XrkkUckSd999526d++uv/76S5UrVy62rubNm2vQoEHmDrabfX8+/PBDjRs3TidOnDDv85NPPtHzzz9vvpYluRZ/FxUVpejo6CLLz4/pLie7Sjf8bAEAAACgzIpabu0KbujChQtydnbW+fPn5eTkdN3tKhpY0207fPiwcnJy1LlzZ4vlly9fVqtWrcyvn3jiCS1fvlwxMTGaPXu2OZCSpJSUFD3//PM3PE5hN41UENDUqlVLGRkZ5mVLly7VzJkzdeTIEWVlZenq1atFPlxPT0+L7pfCEEKSfv31V125csWiQ8vZ2VmNGjUyv96zZ49yc3OL/AF+6dIl3XfffTesv5Ctra3FuUjSH3/8oXHjxmnDhg3KyMhQbm6ucnJyinS7/N3u3buVlJRk0RmVm5urixcvKicnR1WqVLHYvjA0upnHH39cmZmZqlTJ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",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Run comprehensive evaluation on 100 test examples\n",
    "from classifier_tester import ClassifierTester\n",
    "\n",
    "accuracy = ClassifierTester.test(gpt_fine_tuned, test_list, size=100)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
